package com.pine.app.module.security.oauth.provider.token.converter;

import com.google.common.collect.Lists;
import com.pine.app.module.security.core.Authentication;
import com.pine.app.module.security.core.userdetails.User;
import com.pine.app.module.security.core.userdetails.UserDetails;
import com.pine.app.module.security.oauth.user.service.UserDetailService;
import lombok.Setter;

import java.util.*;

/**
 * @author xiaoyuan
 * @create 2020/3/10 0:38
 **/
@Setter
public class DefaultUserAuthenticationConverter implements UserAuthenticationConverter {


    private UserDetailService userDetailsService;

    public DefaultUserAuthenticationConverter(){

    }
    public DefaultUserAuthenticationConverter(UserDetailService userDetailsService){
        this.userDetailsService = userDetailsService;
    }
    @Override
    public Map<String, ?> convertUserAuthentication(Authentication authentication) {
        return null;
    }

    @Override
    public UserDetails extractAuthentication(Map<String, ?> map) {
        if(map.containsKey("user_name")) {
            Object principal = map.get("user_name");
            Set<String> resourceIds = new LinkedHashSet((map.containsKey("resources")?this.getAudience(map): Collections.emptySet()));
            Set<String> roles = new LinkedHashSet((map.containsKey("roles")?this.getRoles(map): Collections.emptySet()));
            UserDetails user;
            if(this.userDetailsService != null) {
                 user = this.userDetailsService.loadUserByUsername((String)map.get("user_name"));
                 return user;
            }
            user = new User(map.get("id").toString(),principal.toString(),"",resourceIds,roles);
            return user;
        }
        return null;
    }

    private Collection<String> getAudience(Map<String, ?> map) {
        Object auds = map.get("resources");
        if(auds instanceof Collection) {
            Collection<String> result = (Collection)auds;
            return result;
        } else {
            return Lists.newArrayList(((String)auds).split(","));
        }
    }

    private Collection<String> getRoles(Map<String, ?> map) {
        Object auds = map.get("roles");
        if(auds instanceof Collection) {
            Collection<String> result = (Collection)auds;
            return result;
        } else {
            return Lists.newArrayList(((String)auds).split(","));
        }
    }
}
